package com.zhiyin.seal.service.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zhiyin.seal.dao.*;
import com.zhiyin.seal.entity.*;
import com.zhiyin.seal.entity.bo.*;
import com.zhiyin.seal.service.StampService;
import com.zhiyin.seal.util.BeanUtil;
import com.zhiyin.seal.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class StampServiceImpl implements StampService {

    @Autowired
    StampDao stampDao;

    @Autowired
    SealDao sealDao;

    @Autowired
    UserDao userDao;

    @Autowired
    CompanyDao companyDao;

    @Autowired
    CompanyUserDao companyUserDao;

    @Override
    public Long startStamp(StartStampBo startStampBo) {
        StampRecordEntity stampRecordEntity = BeanUtil.copy(startStampBo,StampRecordEntity.class);
        stampDao.insertStampRecord(stampRecordEntity);
        return stampRecordEntity.getId();
    }

    @Override
    public Boolean uploadStamp(StampPressBo stampPressBo) {
        List<StampPressBo> stampPressBoList = Lists.newArrayList();
        stampPressBoList.add(stampPressBo);
        return this.uploadStampStorage(stampPressBoList);
    }

    @Override
    public Boolean uploadStampStorage(List<StampPressBo> stampPressBoList) {
        stampPressBoList.forEach(stampPressBo -> {
            String serialNumber = StringUtil.getStampSerialNumber();
            stampPressBo.setSerialNumber(serialNumber);
        });
        List<StampRecordDetailEntity> recordDetailEntityList = BeanUtil.copyList(stampPressBoList,StampRecordDetailEntity.class);
        return stampDao.insertStampRecordDetail(recordDetailEntityList) > 0;
    }

    @Override
    public Long getRecordTotalCount(StampSearchParamsBo stampSearchParamsBo) {
        return stampDao.selectStampRecordTotalCount(BeanUtil.copy(stampSearchParamsBo, StampSearchParamsEntity.class));
    }

    @Override
    public List<StampRecordBo> getRecordList(StampSearchParamsBo stampSearchParamsBo) {
        List<StampRecordEntity> stampRecordEntityList = stampDao.selectStampRecordList(BeanUtil.copy(stampSearchParamsBo, StampSearchParamsEntity.class));

        return buildStampRecordList(stampRecordEntityList);
    }

    @Override
    public StampRecordBo getRecordById(Long stampRecordId) {
        StampRecordEntity stampRecordEntity = stampDao.selectStampRecordById(stampRecordId);
        if(stampRecordEntity == null){
            return null;
        }
        List<StampRecordEntity> stampRecordEntityList = Lists.newArrayList();
        stampRecordEntityList.add(stampRecordEntity);

        return buildStampRecordList(stampRecordEntityList).get(0);
    }

    @Override
    public List<StampRecordBo> getRecordByApplyId(Long applyId) {
        List<StampRecordEntity> stampRecordEntityList = stampDao.selectStampRecordListByApplyId(applyId);

        return buildStampRecordList(stampRecordEntityList);
    }

    @Override
    public Boolean removeStampImageList(String imageUrl) {
        return stampDao.deleteStampImage(imageUrl) > 0;
    }

    @Override
    public List<String> getStampImageList(Long applyId) {
        return stampDao.selectStampImageList(applyId);
    }

    @Override
    public List<StampRecordDetailBo> getRecordDetailList(Long stampRecordId) {
        List<StampRecordDetailEntity> stampRecordDetailEntityList = stampDao.selectRecordDetailList(stampRecordId);
        return BeanUtil.copyList(stampRecordDetailEntityList,StampRecordDetailBo.class);
    }

    @Override
    public Boolean uploadStampImages(StampImageBo stampImageBo) {
        List<ApplyPhotoEntity> applyPhotoEntityList = Lists.newArrayList();
        List<String> imageUrls = stampImageBo.getImageUrls();
        for(int i = 0;i<imageUrls.size();i++){
            String imageUrl = imageUrls.get(i);
            ApplyPhotoEntity applyPhotoEntity = new ApplyPhotoEntity();
            applyPhotoEntity.setApplyId(stampImageBo.getApplyId());
            applyPhotoEntity.setImageUrl(imageUrl);
            applyPhotoEntity.setType(2);
            applyPhotoEntityList.add(applyPhotoEntity);
        }
        if(applyPhotoEntityList.size() > 0){
            // 插入图片信息
            return stampDao.insertApplyStampImages(applyPhotoEntityList) > 0;
        }

        return false;
    }

    @Override
    public Boolean uploadFingerprintRecord(StampRecordFingerprintBo stampRecordFingerprintBo) {
        return stampDao.insertStampRecordFingerprint(BeanUtil.copy(stampRecordFingerprintBo,StampRecordFingerprintEntity.class)) > 0;
    }

    @Override
    public List<StampRecordFingerprintBo> getFingerprintRecordList(String mac, Integer code) {
        return BeanUtil.copyList(stampDao.selectFingerprintRecordList(mac,code),StampRecordFingerprintBo.class);
    }

    @Override
    public Integer selectStampCount() {
        return stampDao.selectStampCount();
    }

    protected List<StampRecordBo> buildStampRecordList(List<StampRecordEntity> stampRecordEntityList){
        List<StampRecordBo> stampRecordBoList = BeanUtil.copyList(stampRecordEntityList,StampRecordBo.class);
        if(stampRecordBoList != null && stampRecordBoList.size() > 0){
            // 关联印章实体
            List<Long> sealIds = Lists.newArrayList();
            sealIds.add(0l);
            Map<Long,Long> stampRecordIdMaps = Maps.newHashMap();
            for (StampRecordEntity stampRecordEntity : stampRecordEntityList) {
                sealIds.add(stampRecordEntity.getSealId());
                stampRecordIdMaps.put(stampRecordEntity.getId(),stampRecordEntity.getSealId());
            }
            // 印章id列表去重复
            sealIds = sealIds.stream().distinct().collect(Collectors.toList());
            List<SealEntity> sealEntityList = sealDao.selectSealListByIdsAndCompany(sealIds,stampRecordBoList.get(0).getCompanyId());
            Map<Long,SealEntity> sealEntityMap = Maps.newHashMap();
            for (SealEntity sealEntity : sealEntityList) {
                sealEntityMap.put(sealEntity.getId(),sealEntity);
            }
            Map<Long,SealEntity> stampRecordSealMaps = Maps.newHashMap();
            stampRecordIdMaps.forEach((startId, sealId) -> {
                stampRecordSealMaps.put(startId,sealEntityMap.get(sealId));
            });
            // 关联用户实体
            List<Long> userIds = Lists.newArrayList();
            userIds.add(0l);
            stampRecordIdMaps = Maps.newHashMap();
            for (StampRecordEntity stampRecordEntity : stampRecordEntityList) {
                userIds.add(stampRecordEntity.getStampUser());
                stampRecordIdMaps.put(stampRecordEntity.getId(),stampRecordEntity.getStampUser());
            }
            // 用户id列表去重复
            userIds = userIds.stream().distinct().collect(Collectors.toList());
            List<UserBo> userBoList = getUserListByUserIdsAndCompany(userIds,stampRecordBoList.get(0).getCompanyId());
            if(userBoList == null){
                return null;
            }
            // 查询公司名称
            String companyName = "";
            CompanyEntity companyEntity = companyDao.selectCompanyById(stampRecordBoList.get(0).getCompanyId());
            if(companyEntity != null){
                companyName = companyEntity.getName();
            }
            Map<Long,UserBo> userBoMap = Maps.newHashMap();
            for (UserBo userBo : userBoList) {
                userBoMap.put(userBo.getId(),userBo);
            }
            Map<Long,UserBo> stampUserMaps = Maps.newHashMap();
            stampRecordIdMaps.forEach((startId, userId) -> {
                stampUserMaps.put(startId,userBoMap.get(userId));
            });

            for (StampRecordBo stampRecordBo : stampRecordBoList) {
                SealEntity sealEntity = stampRecordSealMaps.get(stampRecordBo.getId());
                SealBo sealBo = BeanUtil.copy(sealEntity,SealBo.class);
                stampRecordBo.setSealInfo(sealBo);
                stampRecordBo.setStampUser(stampUserMaps.get(stampRecordBo.getId()));
                stampRecordBo.setCompanyName(companyName);
            }

            return stampRecordBoList;
        }

        return Collections.EMPTY_LIST;
    }

    protected List<UserBo> getUserListByUserIdsAndCompany(List<Long> userIdList,Long companyId){
        if(userIdList.size() == 0){
            userIdList.add(0l);
        }
        List<CompanyUserEntity> companyUserEntityList = companyUserDao.selectUserListByIdsAndCompanyId(userIdList,companyId);
        if(companyUserEntityList != null){
            List<UserBo> userBoList = Lists.newArrayList();
            for (CompanyUserEntity companyUserEntity : companyUserEntityList){
                UserEntity userEntity = userDao.getUserInfoById(companyUserEntity.getUserId());
                if(userEntity != null){
                    UserBo userBo = BeanUtil.copy(userEntity,UserBo.class);
                    userBo.setNickName(companyUserEntity.getUserAlias());
                    userBoList.add(userBo);
                }
            }
            return userBoList;
        }

        return null;
    }
}
